package cn.line5.seam.contexts;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.line5.seam.cache.DBConfigCache;
import cn.line5.seam.exception.DBException;

/**
 * <h1>JDBC资源类</h1> 实现数据库连接的线程安全
 * 
 * @author Liu,Xiaojun
 * @since JDK1.6
 */
public class JdbcContext {
	private static final Logger log = LoggerFactory
			.getLogger(JdbcContext.class);

	private static final ThreadLocal<Connection> connectionThread = new ThreadLocal<Connection>();
	private static final ThreadLocal<String> methodInvokeThread = new ThreadLocal<String>();
	private static DataSource ds = null;

	private static void createDataSource() {
		log.info("Creating datasource now...");
		if (DBConfigCache.jiniName != null
				&& DBConfigCache.jiniName.length() > 0) {
			try {
				InitialContext ctx = new InitialContext();
				ds = (DataSource) ctx.lookup("java:comp/env/"
						+ DBConfigCache.jiniName);
			} catch (NamingException e1) {
				throw new DBException("Can't create datasource by jiniName: "
						+ DBConfigCache.jiniName + ".");
			}
		} else if (DBConfigCache.driverClassName != null
				&& DBConfigCache.driverClassName.length() > 0) {
			Properties p = new Properties();
			p.setProperty("driverClassName", DBConfigCache.driverClassName);
			p.setProperty("url", DBConfigCache.url);
			p.setProperty("password", DBConfigCache.password);
			p.setProperty("username", DBConfigCache.username);
			p.setProperty("maxActive", DBConfigCache.maxActive);
			p.setProperty("maxIdle", DBConfigCache.maxIdle);
			p.setProperty("maxWait", DBConfigCache.maxWait);
			p.setProperty("removeAbandoned",
					String.valueOf(DBConfigCache.removeAbandoned));
			p.setProperty("removeAbandonedTimeout",
					String.valueOf(DBConfigCache.removeAbandonedTimeout));
			p.setProperty("testOnBorrow",
					String.valueOf(DBConfigCache.testOnBorrow));
			p.setProperty("logAbandoned",
					String.valueOf(DBConfigCache.logAbandoned));
			p.setProperty("autoCommit",
					String.valueOf(DBConfigCache.autoCommit));
			try {
				ds = (BasicDataSource) BasicDataSourceFactory
						.createDataSource(p);
			} catch (Exception e) {
				throw new DBException("Can't create datasource.");
			}
		} else {
			log.warn("Can't defined database source.");
		}
	}

	/**
	 * 获取数据库连接
	 */
	public static Connection getConnection() {
		if (ds == null)
			createDataSource();
		Connection conn = connectionThread.get();
		if (conn == null && ds != null) {
			try {
				conn = ds.getConnection();
				connectionThread.set(conn);
			} catch (SQLException e) {
				log.error("Can't create connection...");
				throw new DBException("Can't create connection.");
			}
		}
		return conn;
	}

	/**
	 * 关闭数据库连接，并从数据库资源池从移除连接
	 */
	public static void closeConnection() {
		if (ds == null)
			return;
		Connection conn = connectionThread.get();
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				throw new DBException("Can't close connection.");
			}
			connectionThread.remove();
			conn = null;
		}
	}

	/**
	 * 获取当前调用的方法名称
	 */
	public static String getMethodInvoke() {
		return methodInvokeThread.get();
	}

	/**
	 * 设置当前调用的方法名称
	 * 
	 * @param methodInvoke
	 *            方法名称
	 */
	public static void setMethodInvoke(String methodInvoke) {
		methodInvokeThread.set(methodInvoke);
	}

	/**
	 * 清空当前调用的方法名称
	 */
	public static void clearMethodInvoke() {
		if (methodInvokeThread.get() != null)
			methodInvokeThread.remove();
	}
}